Skip to content

Add type configuration support to the typescript cli plugin #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 27, 2022

Conversation

duncangrant
Copy link
Contributor

This pull request adds type configuration support to cfn resources generated by the cli using the typescript plugin. This matches the same functionality in the java cli plugin.

@ammokhov
Copy link
Contributor

looks like build checks are failing

@ahgittin
Copy link

Thanks for triggering the CI and as you note there is one test failure:

https://github.com/aws-cloudformation/cloudformation-cli-typescript-plugin/runs/7294982721?check_suite_focus=true#step:7:567

E subprocess.CalledProcessError: Command '['/bin/bash', '-c', 'npm install --optional && sam build --debug --build-dir /tmp/pytest-of-runner/pytest-0/test_package_local0/build TypeFunction']' returned non-zero exit status 1.

We'll investigate and fix.

Copy link
Contributor

@ammokhov ammokhov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good to me. Few comments that need your attention. Once those + warnings are resolved, this could be shipped

Comment on lines +165 to +167
configuration_models = resolve_models(
project.configuration_schema, "TypeConfigurationModel"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great to achieve parity with other plugins:

configuration_schema_path =project.root / project.configuration_schema_filename
project.write_configuration_schema(configuration_schema_path)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ammokhov Not sure what this does. As far as I know, we want all the models, TypeConfiguration included to be generated within models.ts. Am I missunderstanding something?

@tbouron
Copy link

tbouron commented Jul 20, 2022

FYI, the python test failing is because the test tries to build a sample TypeScript project, which uses the currently released library. But obviously, this doesn't have the new code we added.

The solution would be to update the python test test_package_local (in tests/plugin/codegen_test.py) to:

  1. generate a tarball of the plugin, using npm pack
  2. updating the sample package.json project to use that tarball

@ahgittin
Copy link

To summarize - we believe the CI test failures are due to a bug in the project's test framework, not this commit, where the test setup creates and tests a TS project which is wired to use the released version of this plugin, rather than the development version of the plugin. Presumably for some code changes this is okay, but if the code change is such that the TS project won't run without the updated plugin, these tests will fail.

We can reproduce locally, and as @tbouron says, if we manually change the package.json in the created TS project to point at a TGZ pack of this project, then it seems to work.

Duncan Grant and others added 3 commits July 26, 2022 08:42
this makes
(1) new version generated code backwards compatible with old version runtime framework (it just won't get type configuration info), and
(2) new version runtime framework backwards compatible with old version generated code (it will ignore type configuration info)

resulting signature is not especially clean but backwards compatibility is worth it.
@ahgittin
Copy link

We've found a sneaky way which seems to allow for backwards compatibility: the TypeConfigurationModel parameter is now the last one, and is optional. This means:

(1) new version generated code is backwards compatible with old version runtime framework (it just won't get type configuration info), and
(2) new version runtime framework is backwards compatible with old version generated code (it will ignore type configuration info)

This should allow the tests to pass, degrade gracefully if not using the latest version of things.

Users should expect TS transpile-time errors about signatures of their handler methods, which now take an additional TypeConfigurationModel parameter, but the compiled JS should run fine. Users can // @ts-ignore those errors or (better) add the additional argument.

cc @ammokhov - Could you kick off the CI workflow to see if it passes here? (We have now confirmed that it passes locally.)

@ahgittin
Copy link

The last couple commits tidy up some unrelated build failures (a test re JS error messages, and a new linter rule in Python) so that -- hopefully -- the build can finally pass reliably!

@codecov
Copy link

codecov bot commented Jul 26, 2022

Codecov Report

Merging #67 (257eeef) into master (ddcfb54) will decrease coverage by 0.54%.
The diff coverage is 76.66%.

❗ Current head 257eeef differs from pull request most recent head 7098a11. Consider uploading reports for the commit 7098a11 to get more accurate results

@@            Coverage Diff             @@
##           master      #67      +/-   ##
==========================================
- Coverage   98.93%   98.38%   -0.55%     
==========================================
  Files          13       13              
  Lines        1215     1237      +22     
  Branches      212      217       +5     
==========================================
+ Hits         1202     1217      +15     
- Misses         13       19       +6     
- Partials        0        1       +1     
Flag Coverage Δ
unittests 98.38% <76.66%> (-0.55%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
python/rpdk/typescript/codegen.py 98.65% <50.00%> (-1.35%) ⬇️
src/resource.ts 96.55% <76.19%> (-1.84%) ⬇️
src/exceptions.ts 100.00% <100.00%> (ø)
src/interface.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ddcfb54...7098a11. Read the comment docs.

* @param logger Logger to proxy requests to default publishers
*/
@handlerEvent(Action.Delete)
public async delete(
session: Optional<SessionProxy>,
request: ResourceHandlerRequest<ResourceModel>,
callbackContext: CallbackContext,
logger: LoggerProxy
logger: LoggerProxy,
typeConfiguration: TypeConfigurationModel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean about changing the order. You guys are the experts on TypeScript here, but curious as to why we cannot use syntax like typeConfiguration?: TypeConfigurationModel here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i also wondered why ? or Optional<> wasn't used here -- technically I think it should be present on callback and logger as well as typeConfiguration. possibly the types admin null already or the signature isn't needed. but we tried to match existing patterns as much as possible since this isn't our codebase.

what we had wanted to do and did previously was to include the typeConfiguration before the logger, to match the java signature. but that is what caused the problem.

previous versions of the framework code of course call the old signature, ie delete(session, request, callback, logger).

in the test failure we were seeing, that old framework code is running, making that exact call, but against a handler ^ based on the new template, expecting the new signature, so with the changes we had made earlier it thinks the 4th parameter is a typeConfiguration when the caller gave a logger there. (the new framework called the new signature, so if you ran new versions at both places it worked fine.)

in the new code because we haven't changed any existing fields, just appended a new 5th, it quite happily accepts calls from the old framework to new code or even new framework to old code -- in the former case it calls the signature with 4 arguments, and those args match, and it passes undefined in for the typeConfiguration, which works fine at runtime since the TS type info is thrown away when converted to JS; and in the latter case it includes the new 5th argument as a typeConfiguration but old handlers only take 4 args which all match and it just ignores the 5th.

@@ -7,8 +7,8 @@ repos:
- repo: https://github.com/ambv/black
rev: stable
hooks:
- id: black
# language_version: python3.6
- id: black
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this indent accidental? if so, is it possible to remove this file from the commit?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably an IDE did that automatically or a linter wanted it. yaml doesn't care and conventions vary whether list items should be indented two spaces or not. i note all the other blocks in this file do indent list items so this change makes it consistent. i'd recommend keeping but happy to remove if you prefer.

@ammokhov
Copy link
Contributor

Thank you for your contribution! This is great addition to the plugin

@ammokhov ammokhov merged commit fbccf14 into aws-cloudformation:master Jul 27, 2022
@ammokhov ammokhov added the enhancement New feature or request label Jul 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants